---
title: SQL queries
sidebar:
  order: 4
---

import QueryBuilderSnippet from '../../../_assets/code/reference/state/sql-queries/query-builder.ts?snippet'
import RawSqlSnippet from '../../../_assets/code/reference/state/sql-queries/raw-sql.ts?snippet'

## Query builder

LiveStore also provides a small query builder for the most common queries. The query builder automatically derives the appropriate result schema internally.

<QueryBuilderSnippet />

## Raw SQL queries

LiveStore supports arbitrary SQL queries on top of SQLite. In order for LiveStore to handle the query results correctly, you need to provide the result schema.

<RawSqlSnippet />

## Best practices

- Query results should be treated as immutable/read-only
- For queries which could return many rows, it's recommended to paginate the results
  - Usually both via paginated/virtualized rendering as well as paginated queries
	- You'll get best query performance by using a `WHERE` clause over an indexed column combined with a `LIMIT` clause. Avoid `OFFSET` as it can be slow on large tables
- For very large/complex queries, it can also make sense to implement incremental view maintenance (IVM) for your queries
  - You can for example do this by have a separate table which is a materialized version of your query results which you update manually (and ideally incrementally) as the underlying data changes.
